
using System.Collections.Generic;
using Nethereum.JsonRpc.Client;
using Nethereum.RPC.Eth.DTOs;
using System.Threading.Tasks;


namespace Nethereum.Geth.RPC.GethEth
{
    ///<Summary>
/// Executes a new message call immediately, without creating a transaction on the block chain. The eth_call method can be used to query internal contract state, to execute validations coded into a contract or even to test what the effect of a transaction would be without running it live.
/// 
/// Parameters
/// The method takes 3 parameters: an unsigned transaction object to execute in read-only mode; the block number to execute the call against; and an optional state override-set to allow executing the call against a modified chain state.
/// 
/// 1. Object - Transaction call object
/// The transaction call object is mandatory and contains all the necessary parameters to execute a read-only EVM contract method.
/// 
/// Field	Type	Bytes	Optional	Description
/// from	Address	20	Yes	Address the transaction is simulated to have been sent from. Defaults to first account in the local keystore or the 0x00..0 address if no local accounts are available.
/// to	Address	20	No	Address the transaction is sent to.
/// gas	Quantity	<8	Yes	Maximum gas allowance for the code execution to avoid infinite loops. Defaults to 2^63 or whatever value the node operator specified via --rpc.gascap.
/// gasPrice	Quantity	<32	Yes	Number of wei to simulate paying for each unit of gas during execution. Defaults to 1 gwei.
/// value	Quantity	<32	Yes	Amount of wei to simulate sending along with the transaction. Defaults to 0.
/// data	Binary	any	Yes	Binary data to send to the target contract. Generally the 4 byte hash of the method signature followed by the ABI encoded parameters. For details please see the Ethereum Contract ABI.
/// Example:
/// 
/// {
///   "from": "0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3",
///   "to":   "0xebe8efa441b9302a0d7eaecc277c09d20d684540",
///   "gas":  "0x1bd7c",
///   "data": "0xd459fc46000000000000000000000000000000000000000000000000000000000046c650dbb5e8cb2bac4d2ed0b1e6475d37361157738801c494ca482f96527eb48f9eec488c2eba92d31baeccfb6968fad5c21a3df93181b43b4cf253b4d572b64172ef000000000000000000000000000000000000000000000000000000000000008c00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000002b85c0c828d7a98633b4e1b65eac0c017502da909420aeade9a280675013df36bdc71cffdf420cef3d24ba4b3f9b980bfbb26bd5e2dcf7795b3519a3fd22ffbb2000000000000000000000000000000000000000000000000000000000000000238fb6606dc2b5e42d00c653372c153da8560de77bd9afaba94b4ab6e4aa11d565d858c761320dbf23a94018d843772349bd9d92301b0ca9ca983a22d86a70628",
/// }
/// 2. Quantity | Tag - Block number or the string latest or pending
/// The block number is mandatory and defines the context (state) against which the specified transaction should be executed. It is not possible to execute calls against reorged blocks; or blocks older than 128 (unless the node is an archive node).
/// 
/// 3. Object - State override set
/// The state override set is an optional address-to-state mapping, where each entry specifies some state to be ephemerally overridden prior to executing the call. Each address maps to an object containing:
/// 
/// Field	Type	Bytes	Optional	Description
/// balance	Quantity	<32	Yes	Fake balance to set for the account before executing the call.
/// nonce	Quantity	<8	Yes	Fake nonce to set for the account before executing the call.
/// code	Binary	any	Yes	Fake EVM bytecode to inject into the account before executing the call.
/// state	Object	any	Yes	Fake key-value mapping to override all slots in the account storage before executing the call.
/// stateDiff	Object	any	Yes	Fake key-value mapping to override individual slots in the account storage before executing the call.
/// The goal of the state override set is manyfold:
/// 
/// It can be used by DApps to reduce the amount of contract code needed to be deployed on chain. Code that simply returns internal state or does pre-defined validations can be kept off chain and fed to the node on-demand.
/// It can be used for smart contract analysis by extending the code deployed on chain with custom methods and invoking them. This avoids having to download and reconstruct the entire state in a sandbox to run custom code against.
/// It can be used to debug smart contracts in an already deployed large suite of contracts by selectively overriding some code or state and seeing how execution changes. Specialized tooling will probably be necessary.
/// Example:
/// 
/// {
///   "0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3": {
///     "balance": "0xde0b6b3a7640000"
///   },
///   "0xebe8efa441b9302a0d7eaecc277c09d20d684540": {
///     "code": "0x...",
///     "state": {
///       ""
///     }
///   }
/// }
/// Return Values
/// The method returns a single Binary consisting the return value of the executed contract call.
/// 
/// Simple example
/// With a synced Rinkeby node with RPC exposed on localhost (geth --rinkeby --http) we can make a call against the Checkpoint Oracle to retrieve the list of administrators:
/// 
/// $ curl --data '{"method":"eth_call","params":[{"to":"0xebe8efa441b9302a0d7eaecc277c09d20d684540","data":"0x45848dfc"},"latest"],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545
/// And the result is an Ethereum ABI encoded list of accounts:
/// 
/// {
///   "id":      1,
///   "jsonrpc": "2.0",
///   "result":  "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000d9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f300000000000000000000000078d1ad571a1a09d60d9bbf25894b44e4c8859595000000000000000000000000286834935f4a8cfb4ff4c77d5770c2775ae2b0e7000000000000000000000000b86e2b0ab5a4b1373e40c51a7c712c70ba2f9f8e"
/// }
/// Just for the sake of completeness, decoded the response is:
/// 
/// 0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3,
/// 0x78d1ad571a1a09d60d9bbf25894b44e4c8859595,
/// 0x286834935f4a8cfb4ff4c77d5770c2775ae2b0e7,
/// 0xb86e2b0ab5a4b1373e40c51a7c712c70ba2f9f8e
/// Override example
/// The above simple example showed how to call a method already exposed by an on-chain smart contract. What if we want to access some data not exposed by it?
/// 
/// We can gut out the original checkpoint oracle contract with one that retains the same fields (to retain the same storage layout), but one that includes a different method set:
/// 
/// pragma solidity ^0.5.10;
/// 
/// contract CheckpointOracle {
///     mapping(address => bool) admins;
///     address[] adminList;
///     uint64 sectionIndex;
///     uint height;
///     bytes32 hash;
///     uint sectionSize;
///     uint processConfirms;
///     uint threshold;
/// 
///     function VotingThreshold() public view returns (uint) {
///         return threshold;
///     }
/// }
/// With a synced Rinkeby node with RPC exposed on localhost (geth --rinkeby --http) we can make a call against the live Checkpoint Oracle, but override its byte code with our own version that has an accessor for the voting threshold field:
/// 
/// $ curl --data '{"method":"eth_call","params":[{"to":"0xebe8efa441b9302a0d7eaecc277c09d20d684540","data":"0x0be5b6ba"}, "latest", {"0xebe8efa441b9302a0d7eaecc277c09d20d684540": {"code":"0x6080604052348015600f57600080fd5b506004361060285760003560e01c80630be5b6ba14602d575b600080fd5b60336045565b60408051918252519081900360200190f35b6007549056fea265627a7a723058206f26bd0433456354d8d1228d8fe524678a8aeeb0594851395bdbd35efc2a65f164736f6c634300050a0032"}}],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545
/// And the result is the Ethereum ABI encoded threshold number:
/// 
/// {
///   "id":      1,
///   "jsonrpc": "2.0",
///   "result":  "0x0000000000000000000000000000000000000000000000000000000000000002"
/// }
/// Just for the sake of completeness, decoded the response is: 2.    
///</Summary>
    public class EthCall : RpcRequestResponseHandler<string>, IEthCall
    {
        public EthCall(IClient client) : base(client,ApiMethods.eth_call.ToString()) { }

        public Task<string> SendRequestAsync(TransactionInput transaction, BlockParameter blockParameter, Dictionary<string, StateChange> stateChanges, object id = null)
        {
            return base.SendRequestAsync(id, transaction, blockParameter, stateChanges);
        }
        public RpcRequest BuildRequest(TransactionInput transaction, BlockParameter blockParameter, Dictionary<string, StateChange> stateChanges, object id = null)
        {
            return base.BuildRequest(id, transaction, blockParameter, stateChanges);
        }
    }
}

